
#include <string.h>

#include "mm32_device.h"
#include "hal_conf.h"
#include "app_process.h"
#include "mm32_port.h"
#include "cmt2300a.h"

// #define SPEAK_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_8)
// #define SPEAK_HIGHT() GPIO_SetBits(GPIOA, GPIO_Pin_8)


// #define MOTOR_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_9)
// #define MOTOR_HIGHT() GPIO_SetBits(GPIOA, GPIO_Pin_9)

// #define ELECTRIC_LOW() GPIO_ResetBits(GPIOA, GPIO_Pin_10)
// #define ELECTRIC_HIGHT() GPIO_SetBits(GPIOA, GPIO_Pin_10)



sys_status_t sys_status;

TIM_OCInitTypeDef       TIM_OCInitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
GPIO_InitTypeDef        GPIO_InitStruct;
RCC_ClocksTypeDef RCC_Clocks;


void key_init()
{
	GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IPD;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOD, ENABLE);
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_6 ;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_FLOATING;
    GPIO_Init(GPIOD, &GPIO_InitStruct);

}
void key_process()
{
	static uint32_t t=0;
	if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0))
	{
		if(t++>3000)
		{
			sys_status.voice_grade=6;
			speaker_didi(1);
			CMT2300A_GoSleep();
			PLATFORM_DelayMS(500);
			NVIC_SystemReset();
		}
		
	}
	else
	{
		t=0;
	}

	if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6))
	{
		sys_status.neck_battery_charging=1;
	}
	else
	{
		sys_status.neck_battery_charging=0;
	}
}

void PWR_GPIO_Configure(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOD, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 |
                                GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
                                GPIO_Pin_12 | GPIO_Pin_15;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_All;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
    GPIO_Init(GPIOC, &GPIO_InitStruct);
    GPIO_Init(GPIOD, &GPIO_InitStruct);
}

void app_process()
{
	speaker_process();
	motor_process();
	electric_process();
	voice_check_process();
}

void TIM1_Configure(void)
{


    RCC_GetClocksFreq(&RCC_Clocks);

    /* Compute the value to be set in ARR regiter to generate signal frequency at 100 Khz */
    uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 2000 ) - 1;

    /* Compute CCR1 value to generate a duty cycle at 80% for channel 1 */
    uint32_t ChannelPulse = ((uint32_t)500 * (TimerPeriod - 1)) / 1000;

    RCC_APB2PeriphClockCmd(RCC_APB2ENR_TIM1, ENABLE);

    TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
    TIM_TimeBaseStruct.TIM_Prescaler         = 0;
    TIM_TimeBaseStruct.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM_TimeBaseStruct.TIM_Period            = TimerPeriod;
    TIM_TimeBaseStruct.TIM_ClockDivision     = TIM_CKD_DIV1;
    TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);

    TIM_OCStructInit(&TIM_OCInitStruct);
    TIM_OCInitStruct.TIM_OCMode       = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState  = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse        = 0;
    TIM_OCInitStruct.TIM_OCPolarity   = TIM_OCPolarity_High;
    TIM_OCInitStruct.TIM_OCIdleState  = TIM_OCIdleState_Set;

    TIM_OCInitStruct.TIM_Pulse = 0;
    TIM_OC1Init(TIM1, &TIM_OCInitStruct);

    TIM_OCInitStruct.TIM_Pulse = 0;
    TIM_OC2Init(TIM1, &TIM_OCInitStruct);

    TIM_OCInitStruct.TIM_Pulse = 0;
    TIM_OC3Init(TIM1, &TIM_OCInitStruct);

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2);    /* TIM1_CH1 */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2);    /* TIM1_CH2 */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2);    /* TIM1_CH3 */

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;//
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    TIM_Cmd(TIM1, ENABLE);

    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

void speaker_didi(uint8_t on_off)
{
	if(on_off)
	{
		uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / (1500+500*sys_status.voice_grade)) - 1;
		TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
		TIM_TimeBaseStruct.TIM_Prescaler         = 0;
		TIM_OCInitStruct.TIM_Pulse = ((uint32_t)500 * (TimerPeriod - 1)) / 1000;
		TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
		TIM_OC1Init(TIM1, &TIM_OCInitStruct);
	}
	else
	{
		uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 4000 ) - 1;
		TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
		TIM_OCInitStruct.TIM_Pulse = 0;
		TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
		TIM_OC1Init(TIM1, &TIM_OCInitStruct);
	}
}

void speaker_process()
{
	static uint32_t n=0;
	static uint8_t last_statue=0;
	if(sys_status.voice)
	{
		last_statue=1;
		if(sys_status.voice_grade%2)
		{
			if(n==0 || n==100 || n==200 || n==300)
			{
				speaker_didi(0);
			}
			else if(n==50 || n==150 || n==250)
			{
				speaker_didi(1);
			}
		}
		else
		{
			if(n==0 || n==100 || n==200 || n==450 || n==550)
			{
				speaker_didi(0);
			}
			else if(n==50 || n==150 || n==400 || n==500)
			{
				speaker_didi(1);
			}
		}
		

		if(n++>600)
		{
			n=0;
			sys_status.voice=0;
		}
	}
	else
	{
		if(last_statue)
		{
			last_statue=0;
			speaker_didi(0);
		}
		n=0;
	}

	
}

void motor_process()
{
	static uint32_t n=0;
	static uint8_t last_statue=0;
	if(sys_status.shock)
	{
		if(last_statue==0)
		{
			
			uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 2000 ) - 1;
			TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
			TIM_TimeBaseStruct.TIM_Prescaler         = 0;
			TIM_OCInitStruct.TIM_Pulse = ((uint32_t)(600+100*sys_status.shock_grade/2) * (TimerPeriod - 1)) / 1000;

			TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
			TIM_OC2Init(TIM1, &TIM_OCInitStruct);
			last_statue=1;

		}

		if(n++>500)
		{
			n=0;
			sys_status.shock=0;
		}
		
	}
	else
	{
		if(last_statue==1)
		{
			
			uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 2000 ) - 1;
			TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
			TIM_OCInitStruct.TIM_Pulse = 0;
			TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
			TIM_OC2Init(TIM1, &TIM_OCInitStruct);
			last_statue=0;

		}
		n=0;

	}
}
void electric_process()
{
	static uint32_t n=0;
	static uint8_t last_statue=0;
	if(sys_status.electric)
	{
		if(last_statue==0)
		{
			uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 2000 ) - 1;
			TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
			TIM_TimeBaseStruct.TIM_Prescaler         = 1;
			TIM_OCInitStruct.TIM_Pulse = ((uint32_t)20 * (TimerPeriod - 1)) / 1000;
			TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
			TIM_OC3Init(TIM1, &TIM_OCInitStruct);
			last_statue=1;

		}

		if(n++>(100+50*sys_status.electric_grade))
		{
			sys_status.electric=0;
			n=0;
		}
		
	}
	else
	{
		if(last_statue==1)
		{
			
			uint32_t TimerPeriod = (RCC_Clocks.PCLK2_Frequency / 1000 ) - 1;
			TIM_TimeBaseStruct.TIM_Period = TimerPeriod;
			TIM_OCInitStruct.TIM_Pulse = 0;
			TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);
			TIM_OC3Init(TIM1, &TIM_OCInitStruct);
			last_statue=0;

		}
		n=0;
	}
}

void voice_check_init()
{
	ADC_InitTypeDef  ADC_InitStruct;
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2ENR_ADC1, ENABLE);

    ADC_StructInit(&ADC_InitStruct);
    ADC_InitStruct.ADC_Resolution         = ADC_Resolution_12b;
    ADC_InitStruct.ADC_PRESCARE           = ADC_PCLK2_PRESCARE_16;
    ADC_InitStruct.ADC_Mode               = ADC_Mode_Continue;
    ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStruct.ADC_ExternalTrigConv   = ADC1_ExternalTrigConv_T1_CC1;
    ADC_InitStruct.ADC_DataAlign          = ADC_DataAlign_Right;
    ADC_Init(ADC1, &ADC_InitStruct);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 0, ADC_Samctl_240_5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 0, ADC_Samctl_240_5);

    ADC_ANY_NUM_Config(ADC1, 2);    
    ADC_ANY_CH_Config(ADC1, 0, ADC_Channel_4);
    ADC_ANY_CH_Config(ADC1, 1, ADC_Channel_5);
    ADC_ANY_Cmd(ADC1, ENABLE);

    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE);

    /* PA5(RV1) PA4(RV2) PA1(RV3) */
    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    ADC_Cmd(ADC1, ENABLE);

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

void voice_check_process()
{
	static uint8_t t=0;
	if(t++>20)
	{
		t=0;
		if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
	    {
			float RV4Voltage=(float)ADC_GetChannelConvertedValue(ADC1, ADC_Channel_4) * (float)3.3 / (float)4096.0;
			float RV5Voltage=(float)ADC_GetChannelConvertedValue(ADC1, ADC_Channel_5) * (float)3.3 / (float)4096.0;
			if(RV4Voltage>3)
			{
				printf("\r\nRV2 Voltage = %0.2f ", RV4Voltage);
			}

			if(RV5Voltage>1.50)
			{
				sys_status.neck_battery_value=100*((RV5Voltage-1.5)/0.4);
			}
			else
			{
				sys_status.neck_battery_value=0;
				
			}

			ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
	    }
	}
	

        
}

